This tutorial focuses on continuous outcome data meta-analysis using
the R meta package.
library(meta)
library(readxl)
The entire dataset was converted into a dataframe format for easier handling and compatibility with the R example analysis. The dataframe structure allows seamless data manipulation and analysis using R’s built-in functions and packages.
ma$bmi
## Author Year mean.e sd.e median.e q1.e q3.e min.e max.e n.e mean.c sd.c
## 1 Study 1 2007 -1.04 1.75 NA NA NA NA NA 37 -1.20 0.55
## 2 Study 2 2011 NA NA 1.21 0.53 1.82 -0.20 2.58 98 NA NA
## 3 Study 3 2009 -0.17 1.96 NA NA NA NA NA 39 -0.85 1.48
## 4 Study 4 2000 NA NA -0.50 -1.47 0.19 -2.44 0.91 69 NA NA
## 5 Study 5 2023 NA NA -0.26 -0.87 0.37 -1.63 1.06 51 NA NA
## 6 Study 6 2006 -0.05 1.77 NA NA NA NA NA 90 -1.74 0.90
## 7 Study 7 2010 -1.03 1.20 NA NA NA NA NA 78 0.36 1.67
## 8 Study 8 2021 NA NA 1.23 0.39 2.11 -0.16 2.88 49 NA NA
## 9 Study 9 2023 NA NA -1.42 -2.24 -0.52 -2.98 0.21 92 NA NA
## median.c q1.c q3.c min.c max.c n.c
## 1 NA NA NA NA NA 44
## 2 -0.50 -1.49 0.04 -2.09 1.03 35
## 3 NA NA NA NA NA 41
## 4 -1.67 -2.24 -1.08 -2.87 -0.41 60
## 5 -1.85 -2.48 -0.96 -3.24 -0.16 97
## 6 NA NA NA NA NA 86
## 7 NA NA NA NA NA 68
## 8 1.12 0.43 2.07 -0.15 2.63 94
## 9 0.23 -0.60 0.99 -1.11 1.79 32
To perform the meta-analysis of continuous outcome data we will use
the metacont() function from the meta package.
We need to provide some instructions for the metacont()
function. These instructions are known as arguments, which can be one,
two, three, or more inputs that the function uses to perform its task.
The main arguments of the metacont() function are:
m.bmi<-metacont(mean.e=mean.e, sd.e=sd.e, n.e=n.e,
mean.c=mean.c, sd.c=sd.c, n.c=n.c,
data = ma$bmi,
method.tau = "REML",
sm = "MD",
studlab = Author)
m.bmi<-metacont(mean.e=mean.e, sd.e=sd.e, n.e=n.e,
median.e=median.e, q1.e=q1.e, q3.e=q3.e,
min.e=min.e, max.e=max.e,
mean.c=mean.c, sd.c=sd.c, n.c=n.c,
median.c=median.c, q1.c=q1.c, q3.c=q3.c,
min.c=min.c, max.c=max.c,
data = ma$bmi,
method.tau = "REML",
sm = "MD",
studlab = Author)
To visualize the results of a meta-analysis conducted with the
metacont() function, we will use the summary()
function. It will generate a summary of the analysis:
summary(m.bmi)
## MD 95%-CI %W(common) %W(random)
## Study 1 0.1600 [-0.4268; 0.7468] 4.4 10.9
## Study 2 1.8248 [ 1.4879; 2.1616] 13.3 11.3
## Study 3 0.6800 [-0.0840; 1.4440] 2.6 10.5
## Study 4 1.0505 [ 0.7635; 1.3375] 18.3 11.3
## Study 5 1.5002 [ 1.2292; 1.7712] 20.5 11.3
## Study 6 1.6900 [ 1.2778; 2.1022] 8.9 11.2
## Study 7 -1.3900 [-1.8680; -0.9120] 6.6 11.1
## Study 8 0.0447 [-0.2777; 0.3670] 14.5 11.3
## Study 9 -1.6167 [-1.9851; -1.2483] 11.1 11.2
##
## Number of studies: k = 9
## Number of observations: o = 1160 (o.e = 603, o.c = 557)
##
## MD 95%-CI z p-value
## Common effect model 0.6513 [ 0.5286; 0.7740] 10.40 < 0.0001
## Random effects model 0.4417 [-0.3921; 1.2756] 1.04 0.2991
##
## Quantifying heterogeneity:
## tau^2 = 1.5770 [0.6922; 5.8535]; tau = 1.2558 [0.8320; 2.4194]
## I^2 = 97.7% [96.8%; 98.3%]; H = 6.60 [5.60; 7.77]
##
## Test of heterogeneity:
## Q d.f. p-value
## 348.09 8 < 0.0001
##
## Details on meta-analytical method:
## - Inverse variance method
## - Restricted maximum-likelihood estimator for tau^2
## - Q-Profile method for confidence interval of tau^2 and tau
To create the forest plot, we will use the forest()
function. Alongside this function, we will include specific arguments to
customize the appearance and content of the forest plot, such as labels,
confidence interval formatting, and display options. These arguments
ensure the plot is clear, informative, and tailored to the dataset being
analyzed.
forest(m.bmi,
smlab="Length of Stay",
layout="Revman",
sortvar=TE,
lab.e="Experimental", label.left="Favors Experimental",
lab.c="Control", label.right="Favors Control",
ff.lr = "bold",
leftcols=c("studlab", "Year", "mean.e","sd.e","n.e",
"mean.c","sd.c","n.c","w.random", "effect", "ci"),
leftlabs = c("Studies", "Year", "Mean", "SD", "Total",
"Mean","SD","Total","Weight","MD","95% CI"),
text.random = "Random effects model",
random=TRUE,
common=FALSE,
test.overall.random=TRUE,
colgap = "3mm",
fs.heading=12,
fs.study=12,
fs.hetset=10,
digits=2,
digits.pval=2,
pooled.totals = TRUE,
col.square="darkcyan", col.square.lines="black",
prediction = T, col.predict = "#CEF2EE", col.predict.lines = "black", ff.predict=1)